package cn.jtool.dig.common.netty.supports;

import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.List;

/**
 * 分包/转义/校验处理
 */
public class PacketProcessing {

	public static byte checkPackage(byte[] data){
		byte crc = 0x00;
		for (int i = 0; i < data.length; i++) {
			crc ^= data[i];
		}
		return crc;
	}

	/**
	 * 数据转义
	 * 
	 * @param data
	 *            {@link Byte} 源数据
	 * @param from
	 *            {@link Byte}[] 需要转义的字节
	 * @param to
	 *            {@link Byte}[][] 转义后的字节
	 * @return
	 */
	public static byte[] escape(byte[] data, byte[] from, byte[][] to) {
		// 统计转义次数
		int count = 0;
		for (int i = 0, length = data.length; i < length; i++) {
			for (byte b : from) {
				if (data[i] == b) {
					count++;
				}
			}
		}
		int index = 0;
		byte[] result = new byte[count + data.length];
		for (int i = 0, i_length = data.length; i < i_length; i++) {
			boolean isEscape = false;// 标识当前字节是否转义
			for (int j = 0, j_length = from.length; j < j_length; j++) {
				if (data[i] == from[j]) {
					result[index++] = to[j][0];
					result[index++] = to[j][1];
					isEscape = true;
				}
			}
			if (!isEscape) {
				result[index++] = data[i];
			}
		}
		return result;
	}

	/**
	 * 数据转义还原
	 * 
	 * @param data
	 *            {@link Byte} 源数据
	 * @param from
	 *            {@link Byte}[] 需要转义还原的字节
	 * @param to
	 *            {@link Byte}[][] 转义还原后的字节
	 * @return
	 */
	public static byte[] unEscape(byte[] data, byte[][] from, byte[] to) {
		int count = 0;// 累计还原次数
		byte[] temp_result = new byte[data.length];
		int index = 0;
		for (int i = 0, i_length = data.length; i < i_length; i++) {
			boolean isUnEscape = false;
			for (int j = 0, j_length = from.length; j < j_length; j++) {
				if (data[i] == from[j][0]) {
					if (i + 1 < i_length) {
						if (data[i + 1] == from[j][1]) {
							temp_result[index++] = to[j];
							i++;
							count++;
							isUnEscape = true;
						}
					}
				}
			}
			if (!isUnEscape) {
				temp_result[index++] = data[i];
			}
		}
		// 如果没有转义还原,直接返回,否则去除最后空节字数据
		if (count == 0) {
			return temp_result;
		}

		byte[] result = new byte[data.length - count];
		System.arraycopy(temp_result, 0, result, 0, result.length);
		return result;
	}

	public static byte[] str2Bcd(String asc) {
		int len = asc.length();
		int mod = len % 2;

		if (mod != 0) {
			asc = "0" + asc;
			len = asc.length();
		}

		byte abt[] = new byte[len];
		if (len >= 2) {
			len = len / 2;
		}

		byte bbt[] = new byte[len];
		abt = asc.getBytes();
		int j, k;

		for (int p = 0, asc_lenght = asc.length() / 2; p < asc_lenght; p++) {
			if ((abt[2 * p] >= '0') && (abt[2 * p] <= '9')) {
				j = abt[2 * p] - '0';
			} else if ((abt[2 * p] >= 'a') && (abt[2 * p] <= 'z')) {
				j = abt[2 * p] - 'a' + 0x0a;
			} else {
				j = abt[2 * p] - 'A' + 0x0a;
			}

			if ((abt[2 * p + 1] >= '0') && (abt[2 * p + 1] <= '9')) {
				k = abt[2 * p + 1] - '0';
			} else if ((abt[2 * p + 1] >= 'a') && (abt[2 * p + 1] <= 'z')) {
				k = abt[2 * p + 1] - 'a' + 0x0a;
			} else {
				k = abt[2 * p + 1] - 'A' + 0x0a;
			}

			int a = (j << 4) + k;
			byte b = (byte) a;
			bbt[p] = b;
		}
		return bbt;
	}
	private static byte[] escapeByte = null;
	private static byte[][] toEscapeByte = null;
	static {
		toEscapeByte = new byte[4][2];
		toEscapeByte[0][0] = 0x7d;
		toEscapeByte[0][1] = 0x01;
		toEscapeByte[1][0] = 0x7d;
		toEscapeByte[1][1] = 0x02;

		toEscapeByte[2][0] = 0x7A;
		toEscapeByte[2][1] = 0x01;
		toEscapeByte[3][0] = 0x7B;
		toEscapeByte[3][1] = 0x02;

		escapeByte = new byte[4];
		escapeByte[0] = 0x7e;
		escapeByte[1] = 0x7d;
		escapeByte[2] = 0x7A;
		escapeByte[3] = 0x7B;
	}
}
